package library.common.view.dialog.base;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

/**
 * @author Created by qiang.hou on 2018/4/3.
 * @version 1.0
 */
public abstract class BaseDialog<T> extends Dialog {

    public BaseDialog(Context context) {
        super(context);
        init();
    }

    public BaseDialog(Context context, int themeResId) {
        super(context, themeResId);
        init();
    }

    protected BaseDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
        init();
    }

    /**
     * common params
     */
    private CommonParams dialogParams = new CommonParams();

    public CommonParams getCommonParams() {
        return dialogParams;
    }

    public void setCommonParams(CommonParams dialogParams) {
        this.dialogParams = dialogParams;
    }

    private void init() {
        Window dialogWindow = getWindow();
        if (dialogWindow != null) {
            // set background TRANSPARENT
            dialogWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            // padding
            dialogWindow.getDecorView().setPadding(
                    dialogParams.paddingLeft >= 0 ? dialogParams.paddingLeft : 0,
                    dialogParams.paddingTop >= 0 ? dialogParams.paddingTop : 0,
                    dialogParams.paddingRight >= 0 ? dialogParams.paddingRight : 0,
                    dialogParams.paddingBottom >= 0 ? dialogParams.paddingBottom : 0);
            /*
             * layout params
             */
            WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
            // width and height
            layoutParams.width = dialogParams.width > 0 ?
                    dialogParams.width :
                    (int) (dialogParams.widthScreenPercent <= 0 || dialogParams.widthScreenPercent > 1 ?
                            WindowManager.LayoutParams.WRAP_CONTENT :
                            getContext().getResources().getDisplayMetrics().widthPixels * dialogParams.widthScreenPercent);
            layoutParams.height = dialogParams.height > 0 ? dialogParams.height : WindowManager.LayoutParams.WRAP_CONTENT;
            // dim
            layoutParams.dimAmount = dialogParams.dimAmount;
            // gravity
            switch (dialogParams.gravity) {
                case Gravity.TOP:
                case Gravity.BOTTOM:
                case Gravity.LEFT:
                case Gravity.RIGHT:
                case Gravity.START:
                case Gravity.END:
                case Gravity.CENTER:
                    layoutParams.gravity = dialogParams.gravity;
                    break;
                default:
                    // default
                    layoutParams.gravity = Gravity.CENTER;
                    break;
            }
            dialogWindow.setAttributes(layoutParams);
        }
        if (returnLayoutId() > 0) {
            View mRootView = LayoutInflater.from(getContext()).inflate(returnLayoutId(), null, false);
            if (null != mRootView) {
                setContentView(mRootView);
                onBindViewData(mRootView);
                initProcess();
            }
        }
    }

    @Override
    public void show() {
        super.show();
    }

    @Override
    public void dismiss() {
        super.dismiss();
        if (null != dialogParams.dismissListener) {
            dialogParams.dismissListener.onDismiss(setResult());
        }
    }

    /**
     * call back when dialog dismiss
     *
     * @return T
     */
    protected abstract T setResult();

    /**
     * get layout id
     *
     * @return layout resource id
     */
    protected abstract int returnLayoutId();

    /**
     * Init data and process
     */
    protected abstract void initProcess();

    /**
     * for user to refresh data to ui
     *
     * @param view mRootView
     */
    protected abstract void onBindViewData(View view);

    /**
     *
     */
    public abstract static class Builder<T extends BaseDialog> {

        /**
         * common params
         */
        private CommonParams dialogParams;

        public Builder() {
            dialogParams = new CommonParams();
        }

        public Builder width(int width) {
            dialogParams.width = width;
            return this;
        }

        public Builder widthScreenPercent(float percent) {
            dialogParams.widthScreenPercent = percent;
            return this;
        }

        public Builder height(int height) {
            dialogParams.height = height;
            return this;
        }

        public Builder gravity(int gravity) {
            dialogParams.gravity = gravity;
            return this;
        }

        public Builder dimAmount(int dimAmount) {
            dialogParams.dimAmount = dimAmount;
            return this;
        }

        public Builder padding(int left, int top, int right, int bottom) {
            dialogParams.paddingLeft = left;
            dialogParams.paddingTop = top;
            dialogParams.paddingRight = right;
            dialogParams.paddingBottom = bottom;
            return this;
        }

        public Builder hasTitle(boolean hasTitle) {
            dialogParams.isHasDialogTitle = hasTitle;
            return this;
        }

        public Builder title(String title) {
            dialogParams.title = title;
            return this;
        }

        public Builder isCancelableOutside(boolean isCancelableOutside) {
            dialogParams.isCancelableOutside = isCancelableOutside;
            return this;
        }

        public Builder setOnDismissListener(CommonParams.OnDismissListener listener) {
            dialogParams.dismissListener = listener;
            return this;
        }

        public T create() {
            T dialog = createDialog();
            dialog.setCommonParams(dialogParams);
            return dialog;
        }

        protected abstract T createDialog();
    }
}
